//standard
#include <vector>
#include <string>
#include <iostream>


// components
#include <tree.h>
#include <stlhelper.h>
#define DEBUG_LEVEL 6
#include <debug_func.h>
#include <tree_ops.h>
#include <print_error.h>

#include "get_arg.h"

using std::vector;
using std::string;
using std::cout;
using std::cin;
using std::istream;
using namespace bcpp_tree_ops;
using namespace bcpp_tree;




//8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888

//	main

//8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888
int main (int argc, char *argv[])
{

	t_program_args args;

	try
	{

	debug_func_cerr(5);

	// we use cout to print progress so flush per call
	cout.setf(std::ios_base::unitbuf);

	std::ios::sync_with_stdio(false);

	if (!process_command_line_options(argc, argv, args))
		return 1;


//    char buff[4096];
//    cin.rdbuf()->pubsetbuf(buff, 32768); // enable buffering


	//
	//	read tree from cin
	//
	args.VERBOSE() << "\tReading tree...\n";
	bcpp_tree::t_tree tree;
	tree.set_sort_by_names(args.sort_by_name);

	unsigned line_cnt = 0;
	cin >> bcpp_tree::t_tree_io_wrapper(tree, line_cnt);


	args.VERBOSE() << "\tCalculating branch lengths...\n";
	// calculate branch lengths
	bcpp_tree_ops::do_calculate_branch_lengths branch_lengths(tree);

	// set node type to none
	std::vector<eNODETYPE>	node_types(tree.get_node_count(), eNONE);

	// print
	op_print_tree_elaborate print_tree_elaborate
								(tree,
								cout,
								branch_lengths.lengths_to_leaves,
								branch_lengths.lengths_to_root,
								node_types,
								3	// precision
								);
	print_tree_elaborate.print();
	}
	catch (std::exception& e)
	{
		std_print_error(args.CERR(), e.what());
		return 1;
	}

	return 0;
}



